#include "jsontable/table_helper.h"
#include "struct_item.h"

template<> void LoadFromStream(ItemClass &entity, std::istream &stream)
{
	StreamHelper::EnumFromStream(entity, stream);
}

template<> void SaveToStream(const ItemClass &entity, std::ostream &stream)
{
	StreamHelper::EnumToStream(entity, stream);
}

template<> void LoadFromText(ItemClass &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ItemClass &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ItemClass &entity, const rapidjson::Value &value)
{
	EnumFromJson(entity, value);
}

template<> void JsonHelper::BlockToJson(const ItemClass &entity, rapidjson::Value &value)
{
	EnumToJson(entity, value);
}

template<> void LoadFromStream(ItemSubClass &entity, std::istream &stream)
{
	StreamHelper::EnumFromStream(entity, stream);
}

template<> void SaveToStream(const ItemSubClass &entity, std::ostream &stream)
{
	StreamHelper::EnumToStream(entity, stream);
}

template<> void LoadFromText(ItemSubClass &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ItemSubClass &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ItemSubClass &entity, const rapidjson::Value &value)
{
	EnumFromJson(entity, value);
}

template<> void JsonHelper::BlockToJson(const ItemSubClass &entity, rapidjson::Value &value)
{
	EnumToJson(entity, value);
}

template<> void LoadFromStream(ItemQuality &entity, std::istream &stream)
{
	StreamHelper::EnumFromStream(entity, stream);
}

template<> void SaveToStream(const ItemQuality &entity, std::ostream &stream)
{
	StreamHelper::EnumToStream(entity, stream);
}

template<> void LoadFromText(ItemQuality &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ItemQuality &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ItemQuality &entity, const rapidjson::Value &value)
{
	EnumFromJson(entity, value);
}

template<> void JsonHelper::BlockToJson(const ItemQuality &entity, rapidjson::Value &value)
{
	EnumToJson(entity, value);
}

template<> void LoadFromStream(ItemPrototype::Flags &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.canUse, stream);
	StreamHelper::FromStream(entity.canSell, stream);
	StreamHelper::FromStream(entity.canDestroy, stream);
	StreamHelper::FromStream(entity.isDestroyAfterUse, stream);
}

template<> void SaveToStream(const ItemPrototype::Flags &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.canUse, stream);
	StreamHelper::ToStream(entity.canSell, stream);
	StreamHelper::ToStream(entity.canDestroy, stream);
	StreamHelper::ToStream(entity.isDestroyAfterUse, stream);
}

template<> void LoadFromText(ItemPrototype::Flags &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ItemPrototype::Flags &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ItemPrototype::Flags &entity, const rapidjson::Value &value)
{
	FromJson(entity.canUse, value, "canUse");
	FromJson(entity.canSell, value, "canSell");
	FromJson(entity.canDestroy, value, "canDestroy");
	FromJson(entity.isDestroyAfterUse, value, "isDestroyAfterUse");
}

template<> void JsonHelper::BlockToJson(const ItemPrototype::Flags &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.canUse, value, "canUse");
	ToJson(entity.canSell, value, "canSell");
	ToJson(entity.canDestroy, value, "canDestroy");
	ToJson(entity.isDestroyAfterUse, value, "isDestroyAfterUse");
}

template<> const char *GetTableName<ItemPrototype>()
{
	return "item_prototype";
}

template<> const char *GetTableKeyName<ItemPrototype>()
{
	return "itemTypeID";
}

template<> uint64 GetTableKeyValue(const ItemPrototype &entity)
{
	return (uint64)entity.itemTypeID;
}

template<> void SetTableKeyValue(ItemPrototype &entity, uint64 key)
{
	entity.itemTypeID = (uint32)key;
}

template<> const char *GetTableFieldNameByIndex<ItemPrototype>(size_t index)
{
	switch (index)
	{
		case 0: return "itemTypeID";
		case 1: return "itemFlags";
		case 2: return "itemClass";
		case 3: return "itemSubClass";
		case 4: return "itemQuality";
		case 5: return "itemLevel";
		case 6: return "itemStack";
		case 7: return "itemSellPrice";
		case 8: return "itemLootId";
		case 9: return "itemSpellId";
		case 10: return "itemSpellLevel";
		case 11: return "itemScriptId";
		case 12: return "itemScriptArgs";
		case 13: return "itemParams";
	}
	return "";
}

template<> ssize_t GetTableFieldIndexByName<ItemPrototype>(const char *name)
{
	if (strcmp(name, "itemTypeID") == 0) return 0;
	if (strcmp(name, "itemFlags") == 0) return 1;
	if (strcmp(name, "itemClass") == 0) return 2;
	if (strcmp(name, "itemSubClass") == 0) return 3;
	if (strcmp(name, "itemQuality") == 0) return 4;
	if (strcmp(name, "itemLevel") == 0) return 5;
	if (strcmp(name, "itemStack") == 0) return 6;
	if (strcmp(name, "itemSellPrice") == 0) return 7;
	if (strcmp(name, "itemLootId") == 0) return 8;
	if (strcmp(name, "itemSpellId") == 0) return 9;
	if (strcmp(name, "itemSpellLevel") == 0) return 10;
	if (strcmp(name, "itemScriptId") == 0) return 11;
	if (strcmp(name, "itemScriptArgs") == 0) return 12;
	if (strcmp(name, "itemParams") == 0) return 13;
	return -1;
}

template<> size_t GetTableFieldNumber<ItemPrototype>()
{
	return 14;
}

template<> std::string GetTableFieldValue(const ItemPrototype &entity, size_t index)
{
	switch (index)
	{
		case 0: return StringHelper::ToString(entity.itemTypeID);
		case 1: return JsonHelper::BlockToJsonText(entity.itemFlags);
		case 2: return StringHelper::ToString(entity.itemClass);
		case 3: return StringHelper::ToString(entity.itemSubClass);
		case 4: return StringHelper::ToString(entity.itemQuality);
		case 5: return StringHelper::ToString(entity.itemLevel);
		case 6: return StringHelper::ToString(entity.itemStack);
		case 7: return StringHelper::ToString(entity.itemSellPrice);
		case 8: return StringHelper::ToString(entity.itemLootId);
		case 9: return StringHelper::ToString(entity.itemSpellId);
		case 10: return StringHelper::ToString(entity.itemSpellLevel);
		case 11: return StringHelper::ToString(entity.itemScriptId);
		case 12: return StringHelper::ToString(entity.itemScriptArgs);
		case 13: return JsonHelper::SequenceToJsonText(entity.itemParams);
	}
	return "";
}

template<> void SetTableFieldValue(ItemPrototype &entity, size_t index, const std::string_view &value)
{
	switch (index)
	{
		case 0: return StringHelper::FromString(entity.itemTypeID, value);
		case 1: return JsonHelper::BlockFromJsonText(entity.itemFlags, value);
		case 2: return StringHelper::FromString(entity.itemClass, value);
		case 3: return StringHelper::FromString(entity.itemSubClass, value);
		case 4: return StringHelper::FromString(entity.itemQuality, value);
		case 5: return StringHelper::FromString(entity.itemLevel, value);
		case 6: return StringHelper::FromString(entity.itemStack, value);
		case 7: return StringHelper::FromString(entity.itemSellPrice, value);
		case 8: return StringHelper::FromString(entity.itemLootId, value);
		case 9: return StringHelper::FromString(entity.itemSpellId, value);
		case 10: return StringHelper::FromString(entity.itemSpellLevel, value);
		case 11: return StringHelper::FromString(entity.itemScriptId, value);
		case 12: return StringHelper::FromString(entity.itemScriptArgs, value);
		case 13: return JsonHelper::SequenceFromJsonText(entity.itemParams, value);
	}
}

template<> void LoadFromStream(ItemPrototype &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.itemTypeID, stream);
	LoadFromStream(entity.itemFlags, stream);
	StreamHelper::FromStream(entity.itemClass, stream);
	StreamHelper::FromStream(entity.itemSubClass, stream);
	StreamHelper::FromStream(entity.itemQuality, stream);
	StreamHelper::FromStream(entity.itemLevel, stream);
	StreamHelper::FromStream(entity.itemStack, stream);
	StreamHelper::FromStream(entity.itemSellPrice, stream);
	StreamHelper::FromStream(entity.itemLootId, stream);
	StreamHelper::FromStream(entity.itemSpellId, stream);
	StreamHelper::FromStream(entity.itemSpellLevel, stream);
	StreamHelper::FromStream(entity.itemScriptId, stream);
	StreamHelper::FromStream(entity.itemScriptArgs, stream);
	StreamHelper::SequenceFromStream(entity.itemParams, stream);
}

template<> void SaveToStream(const ItemPrototype &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.itemTypeID, stream);
	SaveToStream(entity.itemFlags, stream);
	StreamHelper::ToStream(entity.itemClass, stream);
	StreamHelper::ToStream(entity.itemSubClass, stream);
	StreamHelper::ToStream(entity.itemQuality, stream);
	StreamHelper::ToStream(entity.itemLevel, stream);
	StreamHelper::ToStream(entity.itemStack, stream);
	StreamHelper::ToStream(entity.itemSellPrice, stream);
	StreamHelper::ToStream(entity.itemLootId, stream);
	StreamHelper::ToStream(entity.itemSpellId, stream);
	StreamHelper::ToStream(entity.itemSpellLevel, stream);
	StreamHelper::ToStream(entity.itemScriptId, stream);
	StreamHelper::ToStream(entity.itemScriptArgs, stream);
	StreamHelper::SequenceToStream(entity.itemParams, stream);
}

template<> void LoadFromText(ItemPrototype &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ItemPrototype &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ItemPrototype &entity, const rapidjson::Value &value)
{
	FromJson(entity.itemTypeID, value, "itemTypeID");
	BlockFromJson(entity.itemFlags, value, "itemFlags");
	FromJson(entity.itemClass, value, "itemClass");
	FromJson(entity.itemSubClass, value, "itemSubClass");
	FromJson(entity.itemQuality, value, "itemQuality");
	FromJson(entity.itemLevel, value, "itemLevel");
	FromJson(entity.itemStack, value, "itemStack");
	FromJson(entity.itemSellPrice, value, "itemSellPrice");
	FromJson(entity.itemLootId, value, "itemLootId");
	FromJson(entity.itemSpellId, value, "itemSpellId");
	FromJson(entity.itemSpellLevel, value, "itemSpellLevel");
	FromJson(entity.itemScriptId, value, "itemScriptId");
	FromJson(entity.itemScriptArgs, value, "itemScriptArgs");
	SequenceFromJson(entity.itemParams, value, "itemParams");
}

template<> void JsonHelper::BlockToJson(const ItemPrototype &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.itemTypeID, value, "itemTypeID");
	BlockToJson(entity.itemFlags, value, "itemFlags");
	ToJson(entity.itemClass, value, "itemClass");
	ToJson(entity.itemSubClass, value, "itemSubClass");
	ToJson(entity.itemQuality, value, "itemQuality");
	ToJson(entity.itemLevel, value, "itemLevel");
	ToJson(entity.itemStack, value, "itemStack");
	ToJson(entity.itemSellPrice, value, "itemSellPrice");
	ToJson(entity.itemLootId, value, "itemLootId");
	ToJson(entity.itemSpellId, value, "itemSpellId");
	ToJson(entity.itemSpellLevel, value, "itemSpellLevel");
	ToJson(entity.itemScriptId, value, "itemScriptId");
	ToJson(entity.itemScriptArgs, value, "itemScriptArgs");
	SequenceToJson(entity.itemParams, value, "itemParams");
}

template<> void LoadFromStream(ItemEquipPrototype::Attr &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.type, stream);
	StreamHelper::FromStream(entity.value, stream);
}

template<> void SaveToStream(const ItemEquipPrototype::Attr &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.type, stream);
	StreamHelper::ToStream(entity.value, stream);
}

template<> void LoadFromText(ItemEquipPrototype::Attr &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ItemEquipPrototype::Attr &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ItemEquipPrototype::Attr &entity, const rapidjson::Value &value)
{
	FromJson(entity.type, value, "type");
	FromJson(entity.value, value, "value");
}

template<> void JsonHelper::BlockToJson(const ItemEquipPrototype::Attr &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.type, value, "type");
	ToJson(entity.value, value, "value");
}

template<> void LoadFromStream(ItemEquipPrototype::Spell &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.id, stream);
	StreamHelper::FromStream(entity.level, stream);
}

template<> void SaveToStream(const ItemEquipPrototype::Spell &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.id, stream);
	StreamHelper::ToStream(entity.level, stream);
}

template<> void LoadFromText(ItemEquipPrototype::Spell &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ItemEquipPrototype::Spell &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ItemEquipPrototype::Spell &entity, const rapidjson::Value &value)
{
	FromJson(entity.id, value, "id");
	FromJson(entity.level, value, "level");
}

template<> void JsonHelper::BlockToJson(const ItemEquipPrototype::Spell &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.id, value, "id");
	ToJson(entity.level, value, "level");
}

template<> const char *GetTableName<ItemEquipPrototype>()
{
	return "item_equip_prototype";
}

template<> const char *GetTableKeyName<ItemEquipPrototype>()
{
	return "itemTypeID";
}

template<> uint64 GetTableKeyValue(const ItemEquipPrototype &entity)
{
	return (uint64)entity.itemTypeID;
}

template<> void SetTableKeyValue(ItemEquipPrototype &entity, uint64 key)
{
	entity.itemTypeID = (uint32)key;
}

template<> const char *GetTableFieldNameByIndex<ItemEquipPrototype>(size_t index)
{
	switch (index)
	{
		case 0: return "itemTypeID";
		case 1: return "itemEquipAttrs";
		case 2: return "itemEquipSpells";
	}
	return "";
}

template<> ssize_t GetTableFieldIndexByName<ItemEquipPrototype>(const char *name)
{
	if (strcmp(name, "itemTypeID") == 0) return 0;
	if (strcmp(name, "itemEquipAttrs") == 0) return 1;
	if (strcmp(name, "itemEquipSpells") == 0) return 2;
	return -1;
}

template<> size_t GetTableFieldNumber<ItemEquipPrototype>()
{
	return 3;
}

template<> std::string GetTableFieldValue(const ItemEquipPrototype &entity, size_t index)
{
	switch (index)
	{
		case 0: return StringHelper::ToString(entity.itemTypeID);
		case 1: return JsonHelper::BlockSequenceToJsonText(entity.itemEquipAttrs);
		case 2: return JsonHelper::BlockSequenceToJsonText(entity.itemEquipSpells);
	}
	return "";
}

template<> void SetTableFieldValue(ItemEquipPrototype &entity, size_t index, const std::string_view &value)
{
	switch (index)
	{
		case 0: return StringHelper::FromString(entity.itemTypeID, value);
		case 1: return JsonHelper::BlockSequenceFromJsonText(entity.itemEquipAttrs, value);
		case 2: return JsonHelper::BlockSequenceFromJsonText(entity.itemEquipSpells, value);
	}
}

template<> void LoadFromStream(ItemEquipPrototype &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.itemTypeID, stream);
	StreamHelper::BlockSequenceFromStream(entity.itemEquipAttrs, stream);
	StreamHelper::BlockSequenceFromStream(entity.itemEquipSpells, stream);
}

template<> void SaveToStream(const ItemEquipPrototype &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.itemTypeID, stream);
	StreamHelper::BlockSequenceToStream(entity.itemEquipAttrs, stream);
	StreamHelper::BlockSequenceToStream(entity.itemEquipSpells, stream);
}

template<> void LoadFromText(ItemEquipPrototype &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const ItemEquipPrototype &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(ItemEquipPrototype &entity, const rapidjson::Value &value)
{
	FromJson(entity.itemTypeID, value, "itemTypeID");
	BlockSequenceFromJson(entity.itemEquipAttrs, value, "itemEquipAttrs");
	BlockSequenceFromJson(entity.itemEquipSpells, value, "itemEquipSpells");
}

template<> void JsonHelper::BlockToJson(const ItemEquipPrototype &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.itemTypeID, value, "itemTypeID");
	BlockSequenceToJson(entity.itemEquipAttrs, value, "itemEquipAttrs");
	BlockSequenceToJson(entity.itemEquipSpells, value, "itemEquipSpells");
}
